package com.bwie.auth.controller;

import com.bwie.auth.service.AuthService;
import com.bwie.common.constants.Constants;
import com.bwie.common.exceptions.BusinessException;
import com.bwie.common.pojo.req.LoginReq;
import com.bwie.common.pojo.req.SendCodeReq;
import com.bwie.common.pojo.req.SmsLoginReq;
import com.bwie.common.pojo.res.JwtRes;
import com.bwie.common.result.Result;
import com.bwie.common.utils.AesUtil;
import lombok.RequiredArgsConstructor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.TimeUnit;

@RequiredArgsConstructor
@RestController
public class AuthController {
    private final AuthService authService;
    private final RedisTemplate<String, Object> redisTemplate;
    /**
     * 用户名密码-登录
     * @param loginReq
     * @return
     */
    @PostMapping("/login")
    public Result<JwtRes> login(@Validated @RequestBody LoginReq loginReq) {
        String pwd;
        try {
            pwd = AesUtil.decrypt(loginReq.getPwd());
        } catch (Exception e) {
            throw new BusinessException(Constants.DECRYPT_ERROR);
        }

        // 校验密码
        if (!pwd.matches("^(?=.*[A-Za-z])(?=.*[0-9])[A-Za-z0-9]{6,}$")) {
            return Result.error(Constants.PWD_FORMAT_WRONG);
        }

        JwtRes jwtRes = authService.login(loginReq);
        return Result.success(jwtRes);
    }

    /**
     * 发送短信
     * @param sendCodeReq
     * @return
     */
    @PostMapping("/sendCode")
    public Result<Void> sendCode(@Validated @RequestBody SendCodeReq sendCodeReq){
        // 以下可用 AOP 实现
        // 防刷检查（redis记录发送记录）
        String redisKey = Constants.SEND_CODE_KEY + sendCodeReq.getPhone();
        Long count = redisTemplate.opsForValue().increment(redisKey, 1);
        // 1分钟限流
        if (count != null && count == 1) {
            redisTemplate.expire(redisKey, Constants.SEND_CODE_TIMEOUT_NUM, TimeUnit.MINUTES);
        }
        // 若同一时间不止一个请求，则提示频繁
        if (count != null && count > 1) {
            throw new BusinessException(Constants.SEND_TOO_MUCH);
        }
        // 发送短信
        authService.sendCode(sendCodeReq.getPhone());
        return Result.success();
    }

    /**
     * 手机号验证码登录
     * @param smsLoginReq
     * @return
     */
    @PostMapping("/smsLogin")
    public Result<JwtRes> smsLogin(@RequestBody SmsLoginReq smsLoginReq){
        JwtRes jwtRes = authService.smsLogin(smsLoginReq);
        return Result.success(jwtRes);
    }
}
